﻿// <copyright file="MagneticKinectZone.cs" company="Ucaya">
// </copyright>
// <author>Ucaya</author>

namespace KinectExtensions.Nui
{
    #region

    using System;
    using System.ComponentModel;
    using System.Linq.Expressions;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Animation;

    using KinectExtensions.Controls;

    #endregion

    /// <summary>
    ///   TODO: Update summary.
    /// </summary>
    public class MagneticKinectZone : IKinectZone, INotifyPropertyChanged
    {
        #region Constants and Fields

        /// <summary>
        ///   The storyboard.
        /// </summary>
        private Storyboard storyboard;

        #endregion

        #region Public Events

        /// <summary>
        ///   The property changed.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Public Properties

        /// <summary>
        ///   Gets or sets a value indicating whether HideOnCapture.
        /// </summary>
        public bool HideOnCapture { get; set; }

        /// <summary>
        ///   Gets or sets MagneticCenter.
        /// </summary>
        public Point MagneticCenter { get; set; }

        #endregion

        #region Public Methods

        /// <summary>
        ///   The enter.
        /// </summary>
        public virtual void Enter()
        {
        }

        /// <summary>
        ///   The handle cursor move.
        /// </summary>
        /// <param name = "cursor">
        ///   The cursor.
        /// </param>
        /// <param name = "transform">
        ///   The transform.
        /// </param>
        /// <returns>
        ///   The handle cursor move.
        /// </returns>
        public virtual bool HandleCursorMove(KinectCursor cursor, TranslateTransform transform, Point target)
        {
            if (this.storyboard == null)
            {
                this.storyboard = new Storyboard();
                var da = new DoubleAnimation();
                this.storyboard.Children.Add(da);
                Storyboard.SetTarget(da, cursor);
                Storyboard.SetTargetProperty(da, new PropertyPath("(FrameworkElement.RenderTransform).(TranslateTransform.X)"));
                da.From = target.X;
                da.To = this.MagneticCenter.X;
                da.EasingFunction = new SineEase();
                da.Duration = TimeSpan.FromMilliseconds(200);

                da = new DoubleAnimation();
                this.storyboard.Children.Add(da);
                Storyboard.SetTarget(da, cursor);
                Storyboard.SetTargetProperty(da, new PropertyPath("(FrameworkElement.RenderTransform).(TranslateTransform.Y)"));
                da.From = target.Y;
                da.To = this.MagneticCenter.Y;
                da.EasingFunction = new SineEase();
                da.Duration = TimeSpan.FromMilliseconds(200);

                if (this.HideOnCapture)
                {
                    da = new DoubleAnimation();
                    this.storyboard.Children.Add(da);
                    Storyboard.SetTarget(da, cursor);
                    Storyboard.SetTargetProperty(da, new PropertyPath("Opacity"));
                    da.To = 0;
                    da.Duration = TimeSpan.FromMilliseconds(200);
                }
                else
                {
                    da = new DoubleAnimation();
                    this.storyboard.Children.Add(da);
                    Storyboard.SetTarget(da, cursor);
                    Storyboard.SetTargetProperty(da, new PropertyPath("Opacity"));
                    da.To = 1;
                    da.Duration = TimeSpan.Zero;
                }

                this.storyboard.Begin();
            }

            return true;
        }

        /// <summary>
        ///   The leave.
        /// </summary>
        public virtual void Leave()
        {
            if (this.storyboard != null)
            {
                this.storyboard.Stop();
            }

            this.storyboard = null;
        }

        #endregion

        #region Methods

        /// <summary>
        ///   The raise property changed.
        /// </summary>
        /// <param name = "expression">
        ///   The expression.
        /// </param>
        /// <typeparam name = "TProperty">
        /// </typeparam>
        protected void RaisePropertyChanged<TProperty>(Expression<Func<MagneticKinectZone, TProperty>> expression)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(this.GetPropertyName(expression)));
            }
        }

        #endregion
    }
}